package com.zzyl.nursing.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.domain.Room;
import com.zzyl.nursing.mapper.RoomMapper;
import com.zzyl.nursing.service.IRoomService;
import com.zzyl.nursing.vo.BedVo;
import com.zzyl.nursing.vo.DeviceVo;
import com.zzyl.nursing.vo.RoomVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

/**
 * 房间Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-26
 */
@Service
public class RoomServiceImpl extends ServiceImpl<RoomMapper, Room> implements IRoomService {
    @Autowired
    private RoomMapper roomMapper;


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 查询房间
     *
     * @param id 房间主键
     * @return 房间
     */
    @Override
    public Room selectRoomById(Long id) {
        return getById(id);
    }

    /**
     * 查询房间列表
     *
     * @param room 房间
     * @return 房间
     */
    @Override
    public List<Room> selectRoomList(Room room) {
        return roomMapper.selectRoomList(room);
    }

    /**
     * 新增房间
     *
     * @param room 房间
     * @return 结果
     */
    @Override
    public int insertRoom(Room room) {
        return save(room) ? 1 : 0;
    }

    /**
     * 修改房间
     *
     * @param room 房间
     * @return 结果
     */
    @Override
    public int updateRoom(Room room) {
        return updateById(room) ? 1 : 0;
    }

    /**
     * 批量删除房间
     *
     * @param ids 需要删除的房间主键
     * @return 结果
     */
    @Override
    public int deleteRoomByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 根据楼层 id 获取房间视图对象列表
     *
     * @param floorId
     * @return
     */
    @Override
    public List<RoomVo> getRoomsByFloorId(Long floorId) {
        return roomMapper.selectByFloorId(floorId);
    }


    /**
     * 获取所有房间（负责老人）
     *
     * @param floorId
     * @return
     */
    @Override
    public List<RoomVo> getRoomsWithNurByFloorId(Long floorId) {
        return roomMapper.selectByFloorIdWithNur(floorId);
    }

    @Override
    public RoomVo getRoomById(Long roomId) {
        RoomVo roomVo = roomMapper.getRoomById(roomId);
        return roomVo;
    }

    @Override
    public List<RoomVo> getRoomsWithDeviceByFloorId(Long floorId) {

        List<RoomVo> roomList = roomMapper.getRoomsWithDeviceByFloorId(floorId);


        // 判断
        //  1， 判断 查询的列表 是否为 空，如果为空 就没必要从 redis 中获取数据了

        if (CollUtil.isNotEmpty(roomList)) {
            //     此时说明列表不是null,开始从reids中 获取数据

            // 数据 要塞到床位列表和 房间设备列表中 所以要循环遍历房间列表
            roomList.forEach((itemRoomVo) -> {
                // 得到 安装在 房间上的设备
                List<DeviceVo> deviceVos = itemRoomVo.getDeviceVos();

                //     遍历房间上的设备列表，得到1个设备，然后根据设备id 从 redis中获取数据
                //      遍历之前先判断为不为null
                if (CollUtil.isNotEmpty(deviceVos)) {
                    deviceVos.forEach((itemDeviceVo) -> {
                        //     从redis 中 取数据
                        String jsonStr = (String) redisTemplate.boundHashOps(CacheConstants.IOT_DEVICE_LAST_DATA).get(itemDeviceVo.getIotId());
                        //  先判断 从 redis 中 获取的数据 为不为null
                        if (StrUtil.isNotEmpty(jsonStr)) {
                            //     把数据转为list
                            List<DeviceData> list = JSONUtil.toList(jsonStr, DeviceData.class);
                            //      把list 放到对应的字段中
                            itemDeviceVo.setDeviceDataVos(list);

                        }
                    });
                }

            });


            // 获取床上的设备，并把床上的设备数据 放到对应的位置
            roomList.forEach((roomVo) -> {
                //     获取床位列表
                List<BedVo> bedVoList = roomVo.getBedVoList();
                //     判断是否有床位信息
                if (CollUtil.isNotEmpty(bedVoList)) {
                    //     此时说明床位信息 有内容
                    //     循环遍历床位信息
                    bedVoList.forEach((itemBed) -> {
                        //     取出对应的设备列表
                        List<DeviceVo> deviceVos = itemBed.getDeviceVos();
                        //     判断床位上的设备是否为空
                        if (CollUtil.isNotEmpty(deviceVos)) {
                            //     此时说明该房间床位上 有 设备
                            //     遍历设备。得到设备id,并从redis中 获取数据
                            deviceVos.forEach((itemDevice) -> {
                                //    获取设备id
                                String iotId = itemDevice.getIotId();
                                //     判断设备id 是否为空
                                if (StrUtil.isNotEmpty(iotId)) {
                                    //     从redis 中 获取数据
                                    String devicesData = (String) redisTemplate.boundHashOps(CacheConstants.IOT_DEVICE_LAST_DATA).get(iotId);

                                    //     判断从redis中取的值 是否 有值
                                    if (StrUtil.isNotEmpty(devicesData)) {
                                        //     把 string 转为list
                                        List<DeviceData> list = JSONUtil.toList(devicesData, DeviceData.class);
                                        //     把设备数据 list 塞到床位设备数据中

                                        itemDevice.setDeviceDataVos(list);
                                    }
                                }

                            });
                        }


                    });
                }

            });

            // redisTemplate.boundHashOps(CacheConstants.IOT_DEVICE_LAST_DATA).get(设备id,怎么获取)
        }

        return roomList;
    }
}
